package org.xlin.biz.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Order;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

/**
 * 
 * 基础类
 * @author xl
 *
 */
public class AbstBaseDao<T> {

	@Resource
	JdbcTemplate jdbcTemplate;
	
	@Resource
	NamedParameterJdbcTemplate namedParameterJdbcTemplate;
	
	/**
     * Mysql分页查询通用方法
     * @param querySql  查询SQL
     * @param countSql  查询记录数SQL
     * @param whereSql  条件体
     * @param pageable  分页参数
     * @param paramMaps 条件参数
     * @param rowMapper 记录处理
     * @return
     */
    protected Page<T> queryPage4Mysql(StringBuilder querySql, StringBuilder countSql, StringBuilder whereSql,
    		Pageable pageable, Map<String, Object> paramMaps, RowMapper<T> rowMapper) {
        //增加查询条件
        this.handleStringBuilder4Replace(countSql, "{whereSql}", whereSql.toString());
        // 计算总记录数
        int total = this.getCount(countSql.toString(), paramMaps);
        if (total > 0) {
            //增加查询条件
            this.handleStringBuilder4Replace(querySql, "{whereSql}", whereSql.toString());
            //构建排序条件
            handleQuerySql4PageMysql(querySql, pageable);
            List<T> list = this.namesGetList(querySql.toString(), paramMaps, rowMapper);
            return new PageImpl4jqgrid<T>(list, pageable, total);
        }
        //返回空记录
        return new PageImpl4jqgrid<T>(new ArrayList<T>(), pageable, total);
    }
    
    /**
     * 计算总记录数
     * @param countSQL  计算总记录数的count语句
     * @param paramMaps 语句中对应的参数值
     * @return 总记录数
     */
    protected int getCount(String countSQL, Map<String, Object> paramMaps) {
        return this.getNamedParameterJdbcTemplate().queryForObject(countSQL,paramMaps, Integer.class);
    }
    
    /**
     * 获取记录列表
     * @param sql
     * @param condition
     * @param rowMapper
     * @return
     */
    protected List<T> namesGetList(String sql, Map<String, Object> condition, RowMapper<T> rowMapper) {
        return this.getNamedParameterJdbcTemplate().query(sql, condition, rowMapper);
    }
    
    /**
     * 修改记录
     * @param namedSql
     * @param condition
     * @return
     */
    protected int namesUpdateForMap(String namedSql, Map<String, Object> condition) {
        return this.getNamedParameterJdbcTemplate().update(namedSql, condition);
    }
    
    /**
     * 修改记录并返回指定信息
     * @param namedSql
     * @param condition
     * @return
     */
    protected KeyHolder namesUpdateForMapRetrunId(String namedSql, Map<String, Object> condition,String... id) {
    	SqlParameterSource paramSource = new MapSqlParameterSource(condition);
    	KeyHolder keyHolder = new GeneratedKeyHolder();
    	this.getNamedParameterJdbcTemplate().update(namedSql, paramSource, keyHolder , id);
    	return keyHolder;
    }
    
    /**
     * 处理查询语句  绑定排序条件及分页条件(MYSQL)
     * @param querySql
     * @param pageable
     */
    protected void handleQuerySql4PageMysql(StringBuilder querySql, Pageable pageable) {
        if (pageable != null) {
            //增加排序条件
			Iterator<Order> iter = pageable.getSort().iterator();
            //排序条件
			StringBuilder sort = new StringBuilder();
            while (iter.hasNext()) {
            	Order order = iter.next();
                sort.append(order.getProperty())
                	.append(" ")
                	.append(order.getDirection());
                if(iter.hasNext()){
                	sort.append(",");
                }
            }
            if(sort.length()>0){
            	querySql.append(" order by " + sort);
            }
            //读取条数
            querySql.append(" limit " + pageable.getPageSize());
            //起始位置
            querySql.append(" offset " + pageable.getOffset());
        }
    }
    
    /**
     * 替换Stringbuilder
     * @param oldStr
     * @param newStr
     */
    protected void handleStringBuilder4Replace(StringBuilder sb, String oldStr, String newStr) {
        int start = sb.indexOf(oldStr);
        if (start != -1) {
            sb.replace(start, start + oldStr.length(), newStr);
        }
    }

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
		return namedParameterJdbcTemplate;
	}

}
